/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufc.si.tcc.qmusic.model;

import br.ufc.si.tcc.qmusic.interfaces.IAcorde;
import br.ufc.si.tcc.qmusic.properties.Properties;
import br.ufc.si.tcc.qmusic.util.UtilQMusic;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Lucas Ismaily
 */
public class Triade extends Acorde implements IAcorde {

    private Nota tonica;
    private Nota terca;
    private Nota quinta;
    //Essas notas servem para caso alguma Triade enarmônica seja encotrada, iremos sugerir para evitar erro
    // teórico 
    private Nota enarmonicaTerca;
    private Nota enarmonicaQuinta;

    /*
     * Construtor padrão
     */
    public Triade() {
    }

    /*
     * Construtor completo
     */
    public Triade(String tipo, Nota tonica, Nota terca, Nota quinta) {

        this.tipo = tipo;
        this.tonica = tonica;
        this.terca = terca;
        this.quinta = quinta;
    }

    /*
     * Construtor com todas as notas
     */
    public Triade(Nota tonica, Nota terca, Nota quinta) {
        this.tonica = tonica;
        this.terca = terca;
        this.quinta = quinta;
    }

    @Override
    public Nota getEnarmonicaQuinta() {
        return enarmonicaQuinta;
    }

    @Override
    public void setEnarmonicaQuinta(Nota enarmonicaQuinta) {
        this.enarmonicaQuinta = enarmonicaQuinta;
    }

    @Override
    public Nota getEnarmonicaTerca() {
        return enarmonicaTerca;
    }

    @Override
    public void setEnarmonicaTerca(Nota enarmonicaTerca) {
        this.enarmonicaTerca = enarmonicaTerca;
    }

    @Override
    public Nota getQuinta() {
        return quinta;
    }

    @Override
    public void setQuinta(Nota quinta) {
        this.quinta = quinta;
    }

    @Override
    public Nota getTerca() {
        return terca;
    }

    @Override
    public void setTerca(Nota terca) {
        this.terca = terca;
    }

    @Override
    public Nota getTonica() {
        return tonica;
    }

    @Override
    public void setTonica(Nota tonica) {
        this.tonica = tonica;
    }

    @Override
    public boolean empty() {

        if ((tonica == null || tonica.getNota().isEmpty())
                || (terca == null || terca.getNota().isEmpty())
                || (quinta == null || quinta.getNota().isEmpty())) {
            return true;
        }
        return false;
    }

    //intervalo de tercamaior com quinta justa
    public boolean isTriadeMaior() {
        if (empty()) {
            return false;
        }

        List<Nota> notas = new ArrayList<Nota>();
        notas.add(tonica);
        notas.add(terca);
        notas.add(quinta);
        for (int i = 0; i < 3; i++) {
            Nota tonicaTest = notas.get(i);
            for (int j = 0; j < 3; j++) {
                Nota tercaTest = notas.get(j);
                for (int k = 0; k < 3; k++) {
                    Nota quintaTest = notas.get(k);
                    String tercaComp = UtilQMusic.getTercaMaior(tonicaTest).getNota();
                    String quintaComp = UtilQMusic.getQuintaJusta(tonicaTest).getNota();
                    if (tercaComp.equals(tercaTest.getNota()) && quintaComp.equals(quintaTest.getNota())) {
                        tonica = tonicaTest;
                        terca = tercaTest;
                        quinta = quintaTest;
                        return true;
                    }
                }
            }
        }
        return false;
    }

    //intervalo de terca menor com quinta justa
    public boolean isTriadeMenor() {
        if (empty()) {
            return false;
        }
        List<Nota> notas = new ArrayList<Nota>();
        notas.add(tonica);
        notas.add(terca);
        notas.add(quinta);
        for (int i = 0; i < 3; i++) {
            Nota tonicaTest = notas.get(i);
            for (int j = 0; j < 3; j++) {
                Nota tercaTest = notas.get(j);
                for (int k = 0; k < 3; k++) {
                    Nota quintaTest = notas.get(k);
                    String tercaComp = UtilQMusic.getTercaMenor(tonicaTest).getNota();
                    String quintaComp = UtilQMusic.getQuintaJusta(tonicaTest).getNota();
                    if (tercaComp.equals(tercaTest.getNota()) && quintaComp.equals(quintaTest.getNota())) {
                        tonica = tonicaTest;
                        terca = tercaTest;
                        quinta = quintaTest;
                        return true;
                    }
                }
            }
        }
        return false;
    }

    //intervalo de terca menor com quinta diminuta
    public boolean isTriadeDiminuta() {
        if (empty()) {
            return false;
        }
        List<Nota> notas = new ArrayList<Nota>();
        notas.add(tonica);
        notas.add(terca);
        notas.add(quinta);
        for (int i = 0; i < 3; i++) {
            Nota tonicaTest = notas.get(i);
            for (int j = 0; j < 3; j++) {
                Nota tercaTest = notas.get(j);
                for (int k = 0; k < 3; k++) {
                    Nota quintaTest = notas.get(k);
                    String tercaComp = UtilQMusic.getTercaMenor(tonicaTest).getNota();
                    String quintaComp = UtilQMusic.getQuintaDiminuta(tonicaTest).getNota();
                    if (tercaComp.equals(tercaTest.getNota()) && quintaComp.equals(quintaTest.getNota())) {
                        tonica = tonicaTest;
                        terca = tercaTest;
                        quinta = quintaTest;
                        return true;
                    }
                }
            }
        }
        return false;
    }

    //intervalo de terca maior com quinta aumentada
    public boolean isTriadeAumentada() {
        if (empty()) {
            return false;
        }
        List<Nota> notas = new ArrayList<Nota>();
        notas.add(tonica);
        notas.add(terca);
        notas.add(quinta);
        for (int i = 0; i < 3; i++) {
            Nota tonicaTest = notas.get(i);
            for (int j = 0; j < 3; j++) {
                Nota tercaTest = notas.get(j);
                for (int k = 0; k < 3; k++) {
                    Nota quintaTest = notas.get(k);
                    String tercaComp = UtilQMusic.getTercaMaior(tonicaTest).getNota();
                    String quintaComp = UtilQMusic.getQuintaAumentada(tonicaTest).getNota();
                    if (tercaComp.equals(tercaTest.getNota()) && quintaComp.equals(quintaTest.getNota())) {
                        tonica = tonicaTest;
                        terca = tercaTest;
                        quinta = quintaTest;
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public boolean isTriadeEnarmonica() {
        if (empty()) {
            return false;
        }
        Nota tercaAtual = terca;
        Nota quintaAtual = quinta;
        Nota tonicaAtual = tonica;


        List<Nota> notas = new ArrayList<Nota>();
        notas.add(tonica);
        notas.add(terca);
        notas.add(quinta);
        for (int i = 0; i < 3; i++) {
            tonica = notas.get(i);
            for (int j = 0; j < 3; j++) {
                terca = notas.get(j);
                for (int k = 0; k < 3; k++) {
                    quinta = notas.get(k);
                    if (isTriadeEnarmonicaTipos(Properties.AUMENTADA)) {
                        return true;
                    }
                    if (isTriadeEnarmonicaTipos(Properties.MENOR)) {
                        return true;
                    }
                    if (isTriadeEnarmonicaTipos(Properties.MAIOR)) {
                        return true;
                    }
                    if (isTriadeEnarmonicaTipos(Properties.DIMINUTA)) {
                        return true;
                    }
                }
            }
        }
        tonica = tonicaAtual;
        terca = tercaAtual;
        quinta = quintaAtual;
        return false;
    }

    public boolean isTriadeEnarmonicaTipos(String tipo) {

        //variáveis que definem se a nota é alguma nota enarmonica
        boolean hasTerca = false;
        boolean hasQuinta = false;

        //calcula a nota certa para
        String tercaComp = null;
        String quintaComp = null;
        if (tipo.equals(Properties.AUMENTADA)) {
            tercaComp = UtilQMusic.getTercaMaior(tonica).getNota();
            quintaComp = UtilQMusic.getQuintaAumentada(tonica).getNota();
        }
        if (tipo.equals(Properties.MAIOR)) {
            tercaComp = UtilQMusic.getTercaMaior(tonica).getNota();
            quintaComp = UtilQMusic.getQuintaJusta(tonica).getNota();
        }
        if (tipo.equals(Properties.MENOR)) {
            tercaComp = UtilQMusic.getTercaMenor(tonica).getNota();
            quintaComp = UtilQMusic.getQuintaJusta(tonica).getNota();
        }
        if (tipo.equals(Properties.DIMINUTA)) {
            tercaComp = UtilQMusic.getTercaMenor(tonica).getNota();
            quintaComp = UtilQMusic.getQuintaDiminuta(tonica).getNota();
        }

        List<Nota> notasEnarmonicaTerca = UtilQMusic.getNotasEnarmonica(new Nota(tercaComp));
        for (Nota n : notasEnarmonicaTerca) {
            if (n.equals(this.terca)) {
                this.enarmonicaTerca = new Nota(tercaComp);
                hasTerca = true;
                break;
            }
        }
        List<Nota> notasEnarmonicaQuinta = UtilQMusic.getNotasEnarmonica(new Nota(quintaComp));
        for (Nota n : notasEnarmonicaQuinta) {
            if (n.equals(this.quinta)) {
                this.enarmonicaQuinta = new Nota(quintaComp);
                hasQuinta = true;
                break;
            }
        }

        if (hasQuinta && hasTerca) {
            return true;
        } else if (quintaComp.equals(this.quinta.getNota()) && hasTerca) {
            return true;
        } else if (tercaComp.equals(this.terca.getNota()) && hasQuinta) {
            return true;
        }
        return false;
    }

    @Override
    public String getNotacaoABC() {

        if (isTriadeAumentada() || isTriadeEnarmonicaTipos(Properties.AUMENTADA)) {
            return UtilQMusic.convertNoteNameToABCNotation(this.tonica.getNota()) + Properties.SIMBOLO_AUMENTADO;
        }
        if (isTriadeMenor() || isTriadeEnarmonicaTipos(Properties.MENOR)) {
            return UtilQMusic.convertNoteNameToABCNotation(this.tonica.getNota()) + Properties.SIMBOLO_MENOR;
        }
        if (isTriadeMaior() || isTriadeEnarmonicaTipos(Properties.MAIOR)) {
            return UtilQMusic.convertNoteNameToABCNotation(this.tonica.getNota()) + Properties.SIMBOLO_MAIOR;
        }
        if (isTriadeDiminuta() || isTriadeEnarmonicaTipos(Properties.DIMINUTA)) {
            return UtilQMusic.convertNoteNameToABCNotation(this.tonica.getNota()) + Properties.SIMBOLO_DIMINUTO;
        }
        return null;

    }

    //Método Para as tetrades
    @Override
    public Triade getTriade() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setTriade(Triade triade) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Nota getSetima() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setSetima(Nota setima) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isTetradeMaior() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isTetradeMenor() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isTetradeEnarmonica() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Nota getSetimaEnarmonica() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setSetimaEnarmonica(Nota setimaEnarmonica) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
